package controllers

import (
	"myapp/dal/model"
	"myapp/dal/query"
	"myapp/middleware"
	"myapp/validates"
	"net/http"
	"strconv"
	"strings"

	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"golang.org/x/crypto/bcrypt"
	"gorm.io/gorm"
)

type CreateUserInput struct {
	Username string `json:"username" binding:"required"`
	Password string `json:"password" binding:"required"`
	RoleID   int64  `json:"role_id" binding:"required"`
}

func CreateUser(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		var input CreateUserInput
		if err := c.ShouldBindJSON(&input); err != nil {
			c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
			return
		}

		hashedPassword, err := bcrypt.GenerateFromPassword([]byte(input.Password), bcrypt.DefaultCost)
		if err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "密码加密失败"})
			return
		}

		user := model.User{
			Username: input.Username,
			Password: string(hashedPassword),
			RoleID:   input.RoleID,
		}

		if err := db.Create(&user).Error; err != nil {
			c.JSON(http.StatusInternalServerError, gin.H{"error": "创建用户失败"})
			return
		}

		c.JSON(http.StatusOK, gin.H{"message": "用户创建成功"})
	}
}

func ProfileHandler(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		query.SetDefault(db)

		var dto validates.UserProfile
		if err := c.ShouldBindJSON(&dto); err != nil {
			errs, ok := err.(validator.ValidationErrors)
			if !ok {
				// 非validator.ValidationErrors类型错误直接返回
				c.JSON(http.StatusOK, gin.H{
					"code": 1,
					"msg":  err.Error(),
				})
				return
			}
			// validator.ValidationErrors类型错误则进行翻译
			c.JSON(http.StatusOK, gin.H{
				"code": 1,
				"msg":  middleware.GetFirstErrorMessage(errs),
			})
			return
		}

		userId, _ := c.Get("userID")
		if v, ok := userId.(uint); ok {
			var nd *model.UserProfile
			ndExist, _ := query.UserProfile.Where(query.UserProfile.UserID.Eq(int32(v))).Take()
			if ndExist != nil {
				nd = ndExist
			} else {
				// 如果没有找到，创建一个新的 UserProfile
				nd = &model.UserProfile{
					UserID: int32(v), // 这里确保 UserID 被正确初始化
				}
			}

			nd.Nickname = dto.Nickname
			nd.Gender = dto.Gender
			nd.Avatar = dto.Avatar
			nd.Birthday = dto.BirthYear
			nd.Income = dto.Income
			nd.Province = dto.Province
			nd.City = dto.City
			nd.District = dto.District
			nd.Photos = ""
			nd.DatingType = dto.DatingType
			nd.Description = dto.Description
			nd.Interests = strings.Join(dto.Interests, ",")

			if ndExist != nil && ndExist.UserID > 0 {
				query.UserProfile.Where(query.UserProfile.UserID.Eq(int32(v))).Updates(&nd)
			} else {
				query.UserProfile.Create(nd)
			}

			query.User.Where(query.User.ID.Eq(int32(v))).Updates(model.User{IsProfile: 1})

			c.JSON(http.StatusOK, gin.H{"code": 0, "data": nd.UserID})
			return
		}

		c.JSON(http.StatusOK, gin.H{
			"code": 1,
			"msg":  "程序异常",
		})

	}
}

func UserInfoHandler(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		query.SetDefault(db)

		userId, _ := c.Get("userID")
		if v, ok := userId.(uint); ok {

			query.User.CreatedAt.DateFormat("%W %M %Y")
			user, _ := query.User.Where(query.User.ID.Eq(int32(v))).Take()

			c.JSON(http.StatusOK, gin.H{"code": 0, "data": gin.H{
				"user": user,
			}})
			return
		}

		c.JSON(http.StatusOK, gin.H{
			"code": 1,
			"msg":  "程序异常",
		})
	}
}

func VerifyHandler(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		query.SetDefault(db)

		userId, _ := c.Get("userID")
		if v, ok := userId.(uint); ok {
			nd := model.User{
				IsRealVerify: 1,
			}

			query.User.Where(query.User.ID.Eq(int32(v))).Updates(&nd)

			c.JSON(http.StatusOK, gin.H{"code": 0, "data": nd.ID})
			return
		}

		c.JSON(http.StatusOK, gin.H{
			"code": 1,
			"msg":  "程序异常",
		})

	}
}

func RecomdsHandler(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		query.SetDefault(db)

		pagestr, _ := c.GetQuery("page")
		page1, _ := strconv.Atoi(pagestr)
		if page1 <= 1 {
			page1 = 1
		}

		querys := query.UserProfile.Where()

		offset := (page1 - 1) * 5
		needs, _, _ := querys.Order(query.UserProfile.UserID.Desc()).FindByPage(offset, 5)

		userId, _ := c.Get("userID")
		user_id := 0
		if v, ok := userId.(uint); ok {
			user_id = int(v)
		}

		// 将查询结果转换为自定义结构体
		var customNeeds []validates.UserProfile
		for _, need := range needs {
			customNeeds = append(customNeeds, validates.ProcessUserProfile(need, user_id))
		}

		c.JSON(http.StatusOK, gin.H{"code": 0, "data": gin.H{
			"needs": customNeeds,
		}})
	}
}

func ProfileViewHandler(db *gorm.DB) gin.HandlerFunc {
	return func(c *gin.Context) {
		query.SetDefault(db)

		id, _ := strconv.Atoi(c.Param("id"))

		needs, _ := query.UserProfile.Where(query.UserProfile.UserID.Eq(int32(id))).Take()

		userId, _ := c.Get("userID")
		user_id := 0
		if v, ok := userId.(uint); ok {
			user_id = int(v)
		}

		pagestr, _ := c.GetQuery("page")
		page1, _ := strconv.Atoi(pagestr)
		if page1 <= 1 {
			page1 = 1
		}

		querys := query.Trend.Where(query.Trend.UserID.Eq(needs.UserID))

		offset := (page1 - 1) * 5
		trends, _, _ := querys.Order(query.Trend.ID.Desc()).FindByPage(offset, 5)

		// 将查询结果转换为自定义结构体
		var customTrends []validates.Trend
		for _, trend := range trends {
			customTrends = append(customTrends, validates.ProcessTrend(trend, user_id))
		}

		c.JSON(http.StatusOK, gin.H{"code": 0, "data": gin.H{
			"needs":  validates.ProcessUserProfile(needs, user_id),
			"trends": customTrends,
		}})
	}
}
